home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / util / fam_1_1 / part01 / FAM.doc < prev    next >
Text File  |  1990-02-16  |  16KB  |  333 lines

  1.  
  2. This program allows multiple ARexx programs to access a buffered version of
  3. a directory in a consistent and serialized manner. This program and all
  4. derivative works are copyright 1990 Darren New. All Rights Reserved.
  5.  
  6. Permission to use, copy, modify, and distribute this software and its
  7. documentation for any purpose and without fee is hereby granted, provided
  8. that the above copyright notice appear in all copies and that both that
  9. copyright notice and this permission notice appear in supporting
  10. documentation, and that the names of the copyright holder or author not be
  11. used in advertising or publicity pertaining to disstribution of the
  12. software without specific, written prior permission.
  13.  
  14. BOTH THE AUTHOR AND THE COPYRIGHT HOLDER DISCLAIM ALL WARRANTIES WITH
  15. REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
  16. MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDER OR THE
  17. AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  18. DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  19. AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  20. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  
  22. If you use this program, especially if you redistribute it with your own
  23. application, I request that you drop me a note at new@udel.edu (internet)
  24. to make me feel good. Also, if you write a GREP function that may have more
  25. general utility, please feel free to send it to me if you wish for
  26. inclusion in future distributions of FAM.
  27.  
  28.         VERSION 1.1    Feb 1990
  29.  
  30. -------------------------------------------------------------------------
  31.  
  32. This program allows multiple ARexx programs to access a buffered version of
  33. a directory in a consistent and serialized manner. This program and all
  34. derivative works are copyright 1990 Darren New. All Rights Reserved.
  35. In essense, it is freely distributable; see the .doc files for
  36. distribution permissions.
  37.  
  38. This program does several things with the files in a directory.
  39.  
  40. One: it buffers all the names, dates, sizes, and so on, for quick access.
  41.  
  42. Two: it allows a program to "lock" a file, meaning that the file is marked
  43. as locked in the buffer. This locking does not affect the file in any way.
  44. The locking operation is a "test-and-set" type operation (not the TAS
  45. instruction :-).  This can be used to prevent two processes from attempting
  46. to write the file at the same time.
  47.  
  48. Three: it buffers a count of the number of lines in each file if requested.
  49. Files with specific extensions (.zoo, .arc, .lhz, ...) can be excluded from
  50. this count.
  51.  
  52. Four: it allows files with digits in their names to be created atomically
  53. based on the names of files already there. That is, if the directory
  54. contains the files X01, X02, and X03, two programs can request new files
  55. starting with X and one will get X04 and the other will get X05.
  56.  
  57. Five: it allows the first few lines of each file to be buffered in memory.
  58. This allows for quick scans of file headers and such.
  59.  
  60. Six: it allows a user-compiled function to be used in finding files meeting
  61. certain requirements.  For example, the included function returns the names
  62. of files starting with a given string, containing a line beginning with
  63. the given text, and with that line containing a given word. For example,
  64. find files whose name starts with "comp.sys.amiga" with a line starting
  65. with "Subject:" and that line contains the word "FAM". The source code
  66. is not needed to change this function and multiple copies running concurrently
  67. may ue different functions, each LoadSeg'ed at runtime. I believe that
  68. Manx functions can be used with the Lattice executables as no BLink
  69. linking is needed.
  70.  
  71.  
  72. All these operations are available to ARexx programs via an ADDRESS
  73. instruction and OPTIONS RESULTS.  Multiple copies may run concurrently
  74. as the ARexx port and directory name (as well as other parameters)
  75. are specified on the command line. Without ARexx, this program is useless.
  76. Its original intent is to serve as support for applications written
  77. mostly in ARexx.  The source zoo contains the MinRexx and RexxGlue source
  78. for use with Lattice 5.04 (slightly enhanced to handle non-Rexx messages).
  79.  
  80. -------------------------------------------------------------------------
  81.  
  82. TO DO:
  83.  
  84.     Attempt to speed up line-counting by bypassing strchr(), which takes
  85.     about 75% of the time on test cases.
  86.  
  87.     Try adding MEMF_LARGEST to malloc of buffer for entire file in an
  88.     attempt to reduce memory fragmentation during rescan.
  89.  
  90.     Add control-C checking: a control-C will abort a rescan and execute
  91.     an EXPUNGE NOW
  92.  
  93.     For NEWFILE, allow an option of either base 10 or base 36.
  94.     36**2=      1,296
  95.     36**3=     44,656
  96.     36**4=1,679,616
  97.  
  98.     Add an optional parameter that specifies one of four rescan modes:
  99.     0) the default. rescan always counts everything.
  100.     1) rescan scans all names but leaves linecounts as -1.
  101.        When there are no pending REXX messages, find the next file with
  102.        no line count and scan it. Stop after one scan of the list.
  103.        Check for REXX messages after each file scanned.
  104.     2) rescan scans all names but leaves linecounts as -1.
  105.        When GETINFO is called for a file with no linecount then scan
  106.        the file before returning the information if possible.
  107.     3) like (2) except that the information is discarded if not used
  108.        within a "reasonable" time or if memory gets short or ...
  109.     Note that these rescan options will cause a problem for current FAMgrep
  110.     modules. There will need to be returns from FAMgrep saying "rescan it,
  111.     and then I'll look again."
  112.  
  113.     Have the option of saving the buffer out to a file for quick startup?
  114.     Or is this just silly? If done, toss file if older than directory.
  115.     Alternately, reload the file buffer and then rescan, updating
  116.     entries with different dates.
  117.  
  118. When started, the parameters to the program must be as follows:
  119.     argv[0] - program name
  120.     argv[1] - ARexx host port name to use
  121.     argv[2] - Full path to directory
  122.     argv[3] - Executable to load for GREP command
  123.     argv[4] - string of extensions not to examine the contents of. If
  124.           ommitted, no files will be openned during rescans.
  125.     argv[5] - string that terminates line buffering. If ommitted, contents
  126.           of files will not be buffered.
  127.  
  128. It is assumed that you do not wish to recurse into lower-level directories.
  129. This restriction may be lifted in a future version if I need it.
  130.  
  131. If you define CBACK and link with CBACK.O, this will run totally in the
  132. background once the initial startup message is outputted; do not use RUN.
  133. In a binary distribution, this form of the executable would be called
  134. FAM-CBACK.
  135.  
  136. If you define CRES and link with CRES.O, this will be residentable. In a
  137. binary distribution, this would be called FAM-CRES.
  138.  
  139. If you define LMS then this will use the ASDG Low Memory Server if
  140. available. However, the ASDG LMS has been reported to contain bugs. If the
  141. lowmem.library is not around, the low memory checking is disabled. Note,
  142. however, that running out of memory will not crash this program.
  143.  
  144. Currently, the author is using this program as one component of DIBBS,
  145. Darren's Innovative Bulletin Board Server. This bulletin board, soon to be
  146. released as shareware, is a multi-user message handling system written
  147. mostly in ARexx. Another possible use is an ARexx-driven relational
  148. database system with each relation being stored in a separate file. The
  149. attribute names could be stored at the start of each relation, the comment
  150. could store the name of the relation as the user sees it, and the line
  151. count would supply information on the number of tuples in the relation. I
  152. suspect that there are several more applications that could benefit from
  153. this host.
  154.  
  155.  
  156. -------------------------------------------------------------------------
  157.  
  158. The commands that this host accepts are as follows:
  159.  
  160.     VERSION
  161.     Returns a string indicating what version of the program this is.
  162.  
  163.     OPEN
  164.     Causes the directory to be scanned into memory if not already
  165.     there. This list is herein known as the ScanList. Each OPEN must be
  166.     balanced by a CLOSE.
  167.  
  168.     CLOSE [NOW]
  169.     Causes the ScanList to be discarded if there have been more CLOSEs
  170.     than OPENs and CLEAR has been issued. The optional NOW paramter
  171.     causes enough CLOSEs to be issued to balance all outstanding OPENs.
  172.  
  173.     CLEAR
  174.     Causes the ScanList to be discarded at the next time that there
  175.     have been more CLOSEs than OPENs.
  176.  
  177.     EXPUNGE [NOW]
  178.     Causes the program to exit if there have been more CLOSEs than
  179.     OPENs. If there are still outstanding OPENs, causes the program to
  180.     exit when it receives the final CLOSE command.    Note that this will
  181.     take down the ARexx port if and when the directory is closed. With
  182.     the optional keyword "NOW" it will discard the ScanList and then
  183.     expunge, causing errors to be returned to all subsequent callers.
  184.     There is currently no way to undo the effect of an EXPUNGE command
  185.     once issued.
  186.  
  187.     GETIOERR
  188.     Returns in result string the decimal representation of the IoErr()
  189.     value. Handy after OPEN or RESCAN or RESCAN1 returns RC > 0. Note
  190.     that IoErr() of 232 is "NO MORE ENTRIES IN DIRECTORY" and is a
  191.     normal return code from ExNext().
  192.  
  193.     GETDIRNAME
  194.     Returns in result the directory path passed as argv[2].
  195.  
  196.     GETBINEXTENS
  197.     Returns in result the string of extensions passed in argv[4].
  198.     Returns RC=1 if no such argument was given.
  199.  
  200.     GETBUFENDLINE
  201.     Returns in result the string that terminates line buffering as
  202.     passed in argv[5]. Returns RC=1 if no such argument was given.
  203.  
  204.     GETNAMECOUNT
  205.     Returns in result the number of names in the list. This will be
  206.     zero (without error) if the list will need rescanning.
  207.  
  208.     GETNAMES [pad]
  209.     Returns all names, separated by the indicated pad character
  210.     (default is space), sorted alphabetically, that are in the
  211.     ScanList. If finer distinctions are needed, see GREP.
  212.  
  213.     GETINFO name
  214.     Returns the information for the indicated name in the ScanList. The
  215.     information is formatted as
  216.  
  217.     DIR|FILE PROTECTIONS SIZEBYTES SIZELINES DATE TIME LOCK NAME NOTE\nCONTENTS
  218.  
  219.     where DIR|FILE is directory or file.
  220.     PROTECTIONS are HSPARWED in some order for 1-bit protections.
  221.         The string starts with a '-' and contains one character for
  222.         each bit SET. Note that interpretation of some bits are
  223.         funny.
  224.     SIZEBYTES is the size of the file in bytes.
  225.     SIZELINES is the size of the file in lines or -1 if file could not
  226.         be read or -2 if the file has a GETBINEXTENS extension.
  227.     DATE is the last change date of the file.
  228.     TIME is the last change time in seconds since midnight.
  229.     LOCK is N for NEWFILE, - for available, and L for locked.
  230.     NAME is the file name.
  231.     NOTE is the comment on the file.
  232.     CONTENTS is the buffered contents (if any) of the file. Each line
  233.         of contents (including the last) ends with a linefeed. If there
  234.         are no contents then the NOTE field is not ended with a
  235.         newline.
  236.  
  237.     If the file ends in one of the extensions listed in argv[4] then
  238.     the file is assumed to be some sort of binary file and it is not
  239.     opened during a rescan. This means that its lines are not counted
  240.     and that none of the file's contents are buffered. (Argv[4] should
  241.     be all the extensions with the period. For example, ".zoo.arc.exe")
  242.     If the extension is not one of the GETBINEXTENS then it is read
  243.     into memory (if readable) and then the number of newlines is
  244.     counted and stored in the SIZELINES. If the GETBUFENDLINE string is
  245.     found at the beginning of a line, then all lines of the file up to
  246.     but not including the line beginning with the GETBUFENDLINE string
  247.     is buffered and returned by GETINFO. If the contents information is
  248.     not present in spite of having a non-negative SIZELINES then this
  249.     indicates that the file has an extension not in GETBINEXTENS but
  250.     does not contain a line starting with the GETBUFENDLINE string.
  251.     If memory is exhausted attempting to store the contents then no
  252.     contents are stored.
  253.  
  254.     RESCAN [fpat]
  255.     Rescans the directory and rebuilds the ScanList for the files
  256.     matching the indicated pattern. Note that file names placed in the
  257.     ScanList by the NEWFILE command (and not yet subjected to RESCAN1)
  258.     are not modified by this command.
  259.  
  260.     RESCAN1 fname
  261.     Rescans the indicated single file and rebuilds the control
  262.     information for just that file. This is more efficient than RESCAN.
  263.     It also allows a file name created with NEWFILE to become a regular
  264.     file, subject to rescanning and all. It also allows a file that has
  265.     been deleted from the directory to be removed from the ScanList
  266.     without a complete RESCAN.
  267.  
  268.     GREP[pad][pat]
  269.     Looks through all files, handing each file name structure and 'pat'
  270.     to the user's function to determine a match. Returns list of file
  271.     names for which user's function returned true. See below for
  272.     information on the user's function. The first character after the
  273.     keyword GREP (i.e., the fifth character of the command) can be
  274.     anything, not just a space. If it is not a space, it will be used
  275.     as the separation character.
  276.  
  277.     NEWFILE prefix
  278.     Finds in the ScanList the last (alphabetically) file that starts
  279.     with the given prefix, interprets the remainder of that file's name
  280.     as an integer (meaning that the file's name must end in a string of
  281.     digits), adds one to the integer (zero filling on the left to make
  282.     the name as long as the alphabetically previous name), and adds
  283.     that name to the ScanList, and returns the new name. It does all
  284.     this atomically with respect to handling ARexx commands. It does
  285.     not actually create the file. The file is flagged internally in
  286.     such a way as to survive RESCAN calls even if the file does not
  287.     actually exist. If there is no file with the indicated prefix,
  288.     RC=20 is returned. If there is an overflow (i.e., there is a file
  289.     whose name is the prefix followed by some number of '9's), RC=10 is
  290.     returned. In either error case, no name is added to the buffered
  291.     directory list. This command is used to create a new file in a
  292.     directory without possibility of overlapping use of file names.
  293.     Note that once the file is written and closed, the ARexx program
  294.     should call RESCAN1 to update the directory information for real.
  295.     If the user decides to delete the file, calling RESCAN1 when the
  296.     file does not exist will cause it to be removed from the internal
  297.     list.
  298.  
  299.     NEWFILE10 prefix
  300.     A synonym for NEWFILE.
  301.  
  302.     NEWFILE36 prefix
  303.     This functions identically to NEWFILE except that all digits are
  304.     assumed to be in base 36. That is, the digits
  305.         0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
  306.     are used instead of the normal ten. Notice that these are uppercase
  307.     letters and that the letters come after the numbers. This is done
  308.     to allow denser numbers in references to this file. NOT YET
  309.     IMPLEMENTED!!!
  310.  
  311.     LOCKFILE prev new name
  312.     If name is in the ScanList, this looks at it's LOCK status (as
  313.     returned by GETINFO). If the status matches prev (1 character) then
  314.     the status is changed to new and RC=0. Otherwise, RC>0. This is an
  315.     atomic operation with respect to other ARexx messages.
  316.  
  317. ----------------------------------------------------------------------------
  318.  
  319. The user's function called by GREP must be stored in the executable file
  320. named in the command line. At startup, this file is LoadSeg()ed. When the
  321. GREP command is called, this function will be passed a long pointer to
  322. a character (mpat) followed by a pointer to a ScanListNode. It is
  323. expected to return a boolean (0 or 1) in D0. Hence, from C we call
  324.  
  325. ((long (*)(struct ScanListNode *, char *))(GrepSeg))(ScanList, p);
  326.  
  327. and use the result. Hence, the function must have its entry point at the
  328. start of the file, must take its arguments from the stack, must return its
  329. result in D0, and must be serially reusable.
  330.  
  331.  
  332.  
  333.